import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Date;

public class BenchMarkTestTotal {

    final int messagesTotal = 100;
    final int startPort = 40308;
    int sleepTime = 0;

    public static void main(String[] args){
        new BenchMarkTestTotal().testTotal(9);
    }

    private void testTotal(int peerSize) {
        System.out.println("Running test of Total with " + peerSize + " peers and " +
                messagesTotal + " messages sent");
        InetAddress localhost = null;
        try {
            localhost = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

        long start = new Date().getTime(); //mark the start of the test
        //Initiate peers
        MulticastQueueTotalOnly_v2<Integer>[] peers = new MulticastQueueTotalOnly_v2[peerSize];
        for(int peer = 0; peer < peerSize; peer++){
            peers[peer] = new MulticastQueueTotalOnly_v2<Integer>();
        }

        log("FORMING GROUP");
        try {
            peers[0].createGroup(startPort, MulticastQueue.DeliveryGuarantee.TOTAL);
            wait(2);

            for(int i = 1; i < peerSize; i++){
                peers[i].joinGroup(
                        startPort + i,
                        new InetSocketAddress(localhost,startPort),
                        MulticastQueue.DeliveryGuarantee.TOTAL
                );
                wait(5);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        wait(10);
        log("BROADCASTING");
        for (int i=0; i< messagesTotal; i++) {
            peers[i % peerSize].put(i);
        }

        for (int i=0; i< 4; i++) {
            log("waiting");
            wait(100);
        }



        log("LEAVING GROUP");
        for(int i = 0; i < peerSize; i++){
            peers[i].leaveGroup();
            wait(2);
        }

        wait(20);

        log("GETTING MESSAGES");
        for(int i = 0; i < peerSize; i++){
            MulticastMessageTotal msg;
            MulticastMessageTotal oldMsg = peers[i].get();

            while((msg = peers[i].get()) != null){
                System.out.println(oldMsg);
                if(oldMsg.getClock() <= msg.getClock()){
                    oldMsg = msg;
                }
                else{
                    System.out.println("Error, peer " + i + " recieved\n\t" + "msg recieved:" + msg + "\n\t" + "old message: "+ oldMsg);
                    System.exit(-1);
                }
            }
            log("peer " + i + " done getting messages");
        }

        long end = new Date().getTime();
        System.out.println("Benchmark time: " + (end - start) + "ms and sleep=" + sleepTime +"ms" );
        System.out.println("\t Time without sleeps: " + (end-start-sleepTime) + "ms");
        System.exit(1);
    }

    private void log(String msg){
        System.out.println("\t" + msg);
    }

    public void wait(int secs) {
        try {
            Thread.currentThread();
            Thread.sleep(secs * 100);
            sleepTime += secs * 100;
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }
}
